package com.github.gaojh.ioc.bean;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.gaojh.ioc.IocUtil;
import com.github.gaojh.ioc.annotation.Autowired;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.List;

/**
 * @author gaojh
 * @since 2020/3/29
 */
@Slf4j
public class InjectionInitializer implements Initializer {

    private ClassScanner classScanner;

    @Override
    public void init(ClassScanner classScanner) throws Exception {
        this.classScanner = classScanner;

        List<ClassInfo> list = classScanner.getAllClass();
        for (ClassInfo classInfo : list) {
            Object object = IocUtil.getBean(classInfo.getBeanName());
            setFields(object, classInfo.getBeanClass());
        }
    }


    /**
     * 设置Bean的Field
     */
    private void setFields(Object object, Class<?> clazz) throws Exception {
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Autowired.class)) {
                Autowired autowired = field.getAnnotation(Autowired.class);
                setAutowiredField(autowired.value(), object, ReflectUtil.getField(object.getClass(), field.getName()));
            }
        }
    }

    private void setAutowiredField(String fieldBeanName, Object object, Field field) throws Exception {
        String fieldName = StrUtil.isBlank(fieldBeanName) ? classScanner.getBeanName(field.getType()) : fieldBeanName;
        Object fieldObject = IocUtil.getBean(fieldName);
        ReflectUtil.setFieldValue(object, field, fieldObject);
    }
}
